import React, { Component } from 'react';
import { List, AutoSizer } from 'react-virtualized';
import {
    isEmptyArray,
    generateTreeDataMap,
    delMapItem,
    childrenChain,
    parentChain,
    findAllChildren,
    getFilterIdList,
    treeDataMapCheckRenderIdList,
    checkedCheckedList,
    getCheckedCount
} from './tool';
import './index.less'

import { Checkbox } from 'antd'
import PropTypes from 'prop-types';

const defaultProps = {
    style: {
        width: 320,
        height: 800,
        overflow: 'auto'
    },
    showlevel: 0,
    checkbox: {
        enable: true,
        parentChain: true,      // 影响父级节点；
        childrenChain: true,    // 影响子级节点;
        halfChain: true,        // 即使子级节点被全部选中影响父级节点半选；
        initCheckedList: []     // 初始化多选数组
    },
    prefixClassName: 'do',
    paddingLeftLevel: 20
}
let number = 0;
class TreeSelect extends Component {
    constructor(props) {
        super(props);
        this.state = {
            treeData: [],           // 树数据
            treeDataMap: {},        // 树数据映射表
            idList: [],             // 所有列表
            renderIdList: [],       // 渲染的列表
            checkedList: new Map(), // 勾选的Map列表
            searchVal: '',          // 搜索的值
            selectVal: '',          // 选中的条目
            checkbox: {},           // 复选框的配置
            showlevel: 0,           // 展开的层级
            updateListState: false, // 强制更新List组件
            loading: true,           // 加载中。。。
            rootId: [],             //根节点ID集合
            zIndex: 100,             //初始化tree组件zIndex 值  在展开后提高 关闭后还原
            ExpandId: -1,             //记录展开的ID
            ExpandRootId: -1,          //展开过的跟节点
            CloseId: 0,              //记录编辑的ID
            top: this.props.top      //记录弹框的高度
        }
        this.treeNodeRender = this
            .treeNodeRender
            .bind(this);
        this.onClickRow = this
            .onClickRow
            .bind(this);
        this.onClickRowExpand = this
            .onClickRowExpand
            .bind(this);
        this.onChecked = this
            .onChecked
            .bind(this);

        this.cacheIdList = null;
    }

    static getDerivedStateFromProps(nextProps, prevState) {


        const defaultConfig = {
            showlevel: nextProps.showlevel || defaultProps.showlevel,
            checkbox: nextProps.checkbox || defaultProps.checkbox
        }
        if (nextProps.treeData !== prevState.treeData) {
            const initCheckedListVal = defaultConfig.checkbox.enable ? defaultConfig.checkbox.initCheckedList.map((item) => [item.toString(), item.toString()]) : []

            const initCheckedList = new Map(initCheckedListVal)
            let dataMap = []
            dataMap.push(nextProps.treeData)


            const { map, idList, renderIdList, checkedList, rootId } = generateTreeDataMap({}, dataMap, defaultConfig, initCheckedList, prevState.checkedList, nextProps.top)

            defaultConfig.checkbox.enable && checkedCheckedList(map, checkedList, defaultConfig.checkbox)

            return {
                treeData: nextProps.treeData,
                // value: nextProps.value,
                treeDataMap: map,
                idList: idList,
                renderIdList: renderIdList,
                selectVal: nextProps.selectVal || '',
                checkbox: defaultConfig.checkbox,
                showlevel: defaultConfig.showlevel,
                checkedList: checkedList,
                loading: false,
                rootId: rootId,
            }
        }
        return null
    }

    componentDidCatch(err) {
        console.log(err)
    }

    /**
     * [onClickRowExpand 每行Expand符号节点点击事件回调函数]
     * @method onClickRowExpand
     * @param  {[Object]}  item [被点击节点的集合]
     * @param  {[Event]}   e    [事件]
     *
     */
    onClickRowExpand(item, e) {

        const { renderIdList, treeDataMap, updateListState } = this.state
        if (item.isExpand || item.level == 2) return;
        // //只要展开过根节点就记录下来
        let selectRootId = this.state.ExpandRootId;
        if (treeDataMap[item.Id].Pid === 0) {
            selectRootId = item.Id;
        } else {
            selectRootId = item.Pid;
        }
        //关闭根节点
        if (this.state.ExpandRootId !== -1 && this.state.ExpandRootId != item.Pid) {
            this.onClickRowCloseById(this.state.ExpandRootId)
        }

        //子节点关闭
        if (this.state.ExpandId !== -1) {
            if (treeDataMap[this.state.ExpandId].Pid == item.Pid) {
                this.onClickRowCloseById(this.state.ExpandId)
            }
        }
        const { onExpand } = this.props;
        const { Id } = item

        let _renderIdList = renderIdList.concat([])

        // const disabled = item.disabled && (!item.children ||
        // !isEmptyArray(item.children)) if(disabled) {     return }

        //const isExpand = treeDataMap[item.Id].isExpand = !treeDataMap[item.Id].isExpand
        const isExpand = true;
        //const isExpand =true;
        // 展开
        treeDataMap[item.Id].isExpand = true;
        if (!isEmptyArray(item.Child)) {
            // 找到这个val在renderIdList中的索引
            const idx = this.findIdListInValIdx(Id, _renderIdList)
            const _children = item
                .Child
                .concat([])
            // 在这个val后面插入
            _children.unshift(idx + 1, 0);
            Array
                .prototype
                .splice
                .apply(_renderIdList, _children);
        }

        this.setState({
            renderIdList: _renderIdList,
            treeDataMap,
            zIndex: 100 + (item.level + 1),
            ExpandId: item.Id,
            ExpandRootId: selectRootId,
            updateListState: !updateListState
        }, () => {
            this.forceUpdate()
            onExpand && onExpand(item, e)
        })




    }


    onClickRowCloseById = (Id) => {

        setTimeout(() => {

            const { onExpand } = this.props;
            const { renderIdList, treeDataMap, updateListState } = this.state
            let item = treeDataMap[Id];
            let _renderIdList = renderIdList.concat([])
            // const disabled = item.disabled && (!item.children ||
            // !isEmptyArray(item.children)) if(disabled) {     return }


            treeDataMap[Id].isExpand = false;
            // 收缩
            if (!isEmptyArray(item.Child)) {
                // 找到children的所有子节点
                let map = new Map()
                _renderIdList.forEach((_item) => {
                    map.set(_item, _item)
                })

                const arr = findAllChildren(item.Child, treeDataMap)

                arr.forEach((_item) => {
                    treeDataMap[_item].isExpand = false;
                    map.delete(_item)
                })
                _renderIdList = Array.from(map.values())
            }
            this.setState({
                renderIdList: _renderIdList,
                treeDataMap,
                updateListState: !updateListState
            }, () => {
                // onExpand && onExpand(item, e)
            })
        }, 300);

    }


    /**
    * [onClickRowExpand 每行Expand符号节点点击事件回调函数]
    * @method onClickRowExpand
    * @param  {[Object]}  item [被点击节点的集合]
    * @param  {[Event]}   e    [事件]
    *
    */
    onClickRowClose(item, e) {

        setTimeout(() => {


            const { onExpand } = this.props;
            const { renderIdList, treeDataMap, updateListState } = this.state
            const { Id } = item
            let _renderIdList = renderIdList.concat([])
            // const disabled = item.disabled && (!item.children ||
            // !isEmptyArray(item.children)) if(disabled) {     return }


            treeDataMap[Id].isExpand = false;
            // 收缩
            if (!isEmptyArray(item.Child)) {
                // 找到children的所有子节点
                let map = new Map()
                _renderIdList.forEach((_item) => {
                    map.set(_item, _item)
                })

                const arr = findAllChildren(item.Child, treeDataMap)

                arr.forEach((_item) => {
                    treeDataMap[_item].isExpand = false;
                    map.delete(_item)
                })
                _renderIdList = Array.from(map.values())
            }
            this.setState({
                renderIdList: _renderIdList,
                treeDataMap,
                updateListState: !updateListState
            }, () => {
                onExpand && onExpand(item, e)
            })
        }, 300);

    }

    /**
     * [onClickRow 每行节点点击事件回调函数]
     * @method onClickRow
     * @param  {[Object]}  item [被点击节点的集合]
     * @param  {[Event]}   e    [事件]
     *
     */
    onClickRow(item, e) {
        const { onSelect } = this.props;
        const { value } = item

        this.setState({
            selectVal: value,
        }, () => {
            onSelect && onSelect(item, e)
        })
    }
    NodeClose(e) {

        //e && e.stopPropagation();


        const { renderIdList, treeDataMap, updateListState } = this.state
        const { rootId } = this.state;
        let _renderIdList = renderIdList.concat([])
        rootId.forEach((id) => {
            const Id = id
            const item = treeDataMap[Id]

            // const disabled = item.disabled && (!item.children ||
            // !isEmptyArray(item.children)) if(disabled) {     return }


            treeDataMap[Id].isExpand = false;
            // 收缩
            if (!isEmptyArray(item.Child)) {
                // 找到children的所有子节点
                let map = new Map()
                _renderIdList.forEach((_item) => {
                    map.set(_item, _item)
                })

                const arr = findAllChildren(item.Child, treeDataMap)

                arr.forEach((_item) => {
                    treeDataMap[_item].isExpand = false;
                    map.delete(_item)
                })
                _renderIdList = Array.from(map.values())
            }

        })
        this.setState({
            renderIdList: _renderIdList,
            treeDataMap,
            zIndex: 100,
            ExpandId: -1,             //记录展开的ID
            ExpandRootId: -1,          //展开过的跟节点
            updateListState: !updateListState
        })

    }
    /**
     * [checked 节点的选中情况]
     * @method checked
     * @param  {[Object]}  item [被点击节点的集合]
     * @param  {[Event]}   e    [事件]
     *
     */
    onChecked(o, e) {
        let item = o.target.value;
        // e && e.stopPropagation();
        const { onChecked } = this.props
        const { treeDataMap, checkedList, updateListState, checkbox, renderIdList } = this.state
        const { checkStatus, Id } = item
        const { checked } = checkStatus
        // 判断是否是禁用
        const disabled = item.disabled
        if (disabled) {
            return
        }

        // 影响性能，直接修改Map值 const _treeDataMap = Object.assign({}, treeDataMap)
        const _treeDataMap = treeDataMap

        const _checked = !checked;
        const _checkedList = new Map(checkedList);

        // 处理勾选的value List
        if (_checked) {
            _checkedList.set(Id, Id)
        } else {
            delMapItem(_checkedList, Id)
        }

        // 处理treeDataMap的数据状态
        _treeDataMap[Id] = {
            ..._treeDataMap[Id],
            checkStatus: {
                ..._treeDataMap[Id].checkStatus,
                checked: _checked,
                halfChecked: false
            }
        }

        // 处理复选框联动逻辑
        checkbox.parentChain && parentChain(_treeDataMap, _treeDataMap[item.parentVal], checkbox, _checkedList)
        checkbox.childrenChain && childrenChain(_treeDataMap, item.Child, _checked, _checkedList)

        this.setState({
            treeDataMap: _treeDataMap,
            checkedList: _checkedList,
            renderIdList: renderIdList,
            updateListState: !updateListState
        }, () => {
            let selectListIds = Array.from(this.state.checkedList.keys());
            let selectItemsId = []
            let selectItemsName = []
            selectListIds.forEach((value, index) => {
                let node = this.state.treeDataMap[value];
                selectItemsId.push(node.Id);
                selectItemsName.push(node.Name);
            })
            onChecked && onChecked(selectItemsId, selectItemsName, e)
        })
    }


    // 查找在idList中val的索引
    findIdListInValIdx(val, idList) {
        return idList.indexOf(val)
    }

    // 渲染TreeNode
    treeNodeRender({
        index, // Index of row
        // isScrolling, // The List is currently being scrolled isVisible,   // This row
        // is visible within the List (eg it is not an overscanned row) key,         //
        // Unique key within array of rendered rows parent,      // Reference to the
        // parent List (instance)
        style // Style object to be applied to row (to position it);
        // This must be passed through to the rendered row element.
    }) {

        const { checkbox, customIconRender, customTitleRender, top, left } = this.props
        const { idList, treeDataMap, renderIdList, selectVal } = this.state
        const prefixClassName = defaultProps.prefixClassName;
        const idx = renderIdList[index]

        const item = treeDataMap[idx];

        if (!item) {
            return
        }


        if (item.Pid && item.Pid !== 0 && !treeDataMap[item.Pid].isExpand) {
            // 父级节点属性为不展开，子节点不应该显示
            throw new Error('this item should not be show')
        }

        let _style = {
            ...style,
            //(126 * (item.RootIndex - 1 ) 是算出根节点的排列居左的位置
            //defaultProps.paddingLeftLevel * item.level 算出子节点相对根节点 居左多少像素，一个层级为 defaultProps.paddingLeftLevel
            //marginLeft: (126 * (item.RootIndex ) + (item.level === 1 ? 63 : 0) + defaultProps.paddingLeftLevel * item.level),
            top: item.top,
            //marginLeft: (defaultProps.paddingLeftLevel * item.level),
            zIndex: 200 + item.level,

        }
        if (item.level == 1) {
            _style = {
                ...style,
                marginLeft: (defaultProps.paddingLeftLevel * item.level),
            }
        }
        else if (item.level == 2) {
            _style = {
                ...style,
                marginLeft: 100,
            }
        }


        const checkedClassName = item.checkStatus.checked
            ? `${prefixClassName}-checkbox-checked`
            : ''
        const halfCheckedClassName = !item.checkStatus.checked && item.checkStatus.halfChecked
            ? `${prefixClassName}-checkbox-halfChecked`
            : ''
        const disabled = item.disabled && (!item.Child || !isEmptyArray(item.Child))

        const isSelectVal = selectVal == item.Id
        const _checkbox = checkbox || defaultProps.checkbox

        return (

            <div
                key={item.Id}
                style={{
                    ..._style,
                    width: 'auto',
                    top: item.top,
                    backgroundColor: '#fff',
                    zIndex: 200 + item.level
                }}
                onMouseMove={(e) => this.onClickRowExpand(item, e)}
                //onClick={(e) => this.onClickRowExpand(item, e)}
                className={`${prefixClassName}-TreeNode`}>
                <div

                    className={`${prefixClassName}-fadeIn ${item.disabled
                        ? 'disabled'
                        : ''}`}>

                    {
                        // _checkbox.enable && !disabled && <div
                        //     onClick={(e) => this.onChecked(item, e)}
                        //     className={`${prefixClassName}-checkbox ${checkedClassName} ${halfCheckedClassName}`}>
                        //     <span
                        //         className={`${prefixClassName}-checkbox-inner ${disabled
                        //             ? 'disabled'
                        //             : ''}`}></span>
                        // </div>
                        _checkbox.enable && !disabled &&
                        <div>
                            <Checkbox
                                onChange={this.onChecked}
                                checked={item.checkStatus.checked}
                                indeterminate={item.checkStatus.checked ? false : item.checkStatus.halfChecked}
                                value={item}>

                                {item.Name}
                            </Checkbox>
                            <span className='checkboxCount'>{(item.checkStatus.halfChecked || item.checkStatus.checked) && (item.level < 2) ? `(${getCheckedCount(item, treeDataMap)})` : null} </span>
                        </div>
                    }
                    <div className={`${prefixClassName}-expandIcon`} >
                        {!isEmptyArray(item.Child) && <i className={`${item.isExpand && prefixClassName + '-expand'}`} ></i>}
                    </div>
                    <div
                        //onClick={(e) => this.onClickRow(item, e)}
                        title={item.title}

                        className={`${prefixClassName}-title ${isSelectVal
                            ? 'active'
                            : ''}`}>
                        {customTitleRender
                            ? customTitleRender(item)
                            : item.title}
                    </div>
                    <div className={`${prefixClassName}-customIcon`}>
                        {customIconRender
                            ? customIconRender(item)
                            : ''
                        }
                    </div>
                </div>
            </div>
        )
    }



    render() {
        const { style, wrapperClassName, checkbox, left, top } = this.props;
        const {
            treeDataMap,
            renderIdList,
            searchVal,
            checkedList,
            selectVal,
            updateListState,
            loading,
            rootId,

        } = this.state;
        console.log(treeDataMap,checkedList,renderIdList,searchVal,selectVal)
        const _style = style || defaultProps.style;
        const prefixClassName = defaultProps.prefixClassName;
        const _className = `${prefixClassName}-TreeSelect ${wrapperClassName || ''}`
        let istree = false;
        for (let i = 0; i < renderIdList.length; i++) {
            let item = renderIdList[i]
            if (treeDataMap[item].level > 1) {
                istree = true;
                continue;
            }
        }

        const width = istree ? 300 : 220


        if (loading) {
            return (
                <div

                    className={_className}
                    style={{
                        width: _style.width
                    }}>
                    <div className="spinner">
                        <div className="spinner-container container1">
                            <div className="circle1"></div>
                            <div className="circle2"></div>
                            <div className="circle3"></div>
                            <div className="circle4"></div>
                        </div>
                        <div className="spinner-container container2">
                            <div className="circle1"></div>
                            <div className="circle2"></div>
                            <div className="circle3"></div>
                            <div className="circle4"></div>
                        </div>
                        <div className="spinner-container container3">
                            <div className="circle1"></div>
                            <div className="circle2"></div>
                            <div className="circle3"></div>
                            <div className="circle4"></div>
                        </div>
                    </div>
                </div>
            );
        }
        return (
            <div
                onMouseLeave={(e) => this.NodeClose(e)}
                className={_className}
                style={{
                    width: 50,

                }}>

                <div
                    className={`${prefixClassName}-TreeSelectList`}
                    style={{
                        ..._style,
                        position: 'absolute',
                        zIndex: this.state.zIndex,
                        left: left,
                        top: top,
                        width: width,
                        height: 30,
                        //op:top
                    }}>
                    <List

                        width={width}
                        height={300}
                        autoHeight={true}
                        rowCount={renderIdList.length}
                        rowHeight={22}
                        rowRenderer={this.treeNodeRender}
                        overscanRowCount={200}
                        autoContainerWidth={true}
                        treeDataMap={treeDataMap}
                        checkedList={checkedList}
                        selectVal={selectVal}
                        updateListState={updateListState}
                        checkbox={checkbox} />

                </div>
            </div>
        );
    }
}

// [propTypes 属性类型定义]
TreeSelect.propTypes = {
    treeData: PropTypes.array.isRequired,   // 元数据
    style: PropTypes.object,                // 样式
    checkbox: PropTypes.object,             // 复选框配置
    showlevel: PropTypes.number,            // 显示层级
    selectVal: PropTypes.string,            // 选中的值
    onSelect: PropTypes.func,               // 选择节点的回调函数
    onExpand: PropTypes.func,               // 选择Expand符号的回调函数
    onChecked: PropTypes.func,              // 复选框勾选的回调函数
    wrapperClassName: PropTypes.string,     // 扩展classname
    customIconRender: PropTypes.func,       // 自定义扩展Icon渲染
    customTitleRender: PropTypes.func,      // 自定义标题渲染
};

export default TreeSelect;
